package com.jevons.muffin.encrypt;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 哈希算法工具类--SHA-1/SHA-256/SHA-512/MD5
 * <p>
 * create at:  2016/8/26
 */
public class HashCoder {

    private static final String TAG = HashCoder.class.getSimpleName();
    private static final char[] hexDigits = "0123456789ABCDEF".toCharArray();

    public enum HashType {
        MD5,
        SHA1,
        SHA256,
        SHA512
    }

    /**
     * 获取hash加密后的字符串
     *
     * @param str      需要加密的字符串
     * @param hashType 加密类型
     * @return String
     */
    public static String getHashCoder(String str, HashType hashType) {
        //获取哈希加密类型
        String coderType = getHashValue(hashType);

        try {
            MessageDigest md5 = MessageDigest.getInstance(coderType);
            md5.update(str.getBytes());
            byte[] buffer = md5.digest();
            int length = buffer.length;
            char[] strs = new char[length * 2];
            int k = 0;
            for (int i = 0; i < length; i++) {
                // 进制字符的转换
                byte byte0 = buffer[i];
                strs[k++] = hexDigits[byte0 >>> 4 & 0xf];
                strs[k++] = hexDigits[byte0 & 0xf];
            }

            return new String(strs);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return "";
    }

    /**
     * 获取hash加密后的字符串
     *
     * @param in       InputStream 需要加密的流
     * @param hashType 加密类型
     * @return String
     */
    public static String getHashCoder(InputStream in, HashType hashType) {
        //获取哈希加密类型
        String coderType = getHashValue(hashType);

        int bufferSize = 256 * 1024;
        DigestInputStream digestInputStream = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(coderType);
            digestInputStream = new DigestInputStream(in, messageDigest);
            byte[] buffer = new byte[bufferSize];
            while (digestInputStream.read(buffer) > 0) ;
            messageDigest = digestInputStream.getMessageDigest();
            byte[] resultByteArray = messageDigest.digest();
            char[] resultCharArray = new char[resultByteArray.length * 2];
            int index = 0;
            for (byte b : resultByteArray) {
                resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
                resultCharArray[index++] = hexDigits[b & 0xf];
            }
            return new String(resultCharArray);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, e.toString());
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        } finally {
            try {
                if (digestInputStream != null)
                    digestInputStream.close();
            } catch (Exception e) {
                Log.e(TAG, e.toString());
            }
        }
        return null;
    }

    /**
     * 获取Hash加密类型
     *
     * @param type Hash加密类型
     * @return Hash加密类型
     */
    private static String getHashValue(HashType type) {
        switch (type) {
            case MD5:
                return "MD5";
            case SHA1:
                return "SHA-1";
            case SHA256:
                return "SHA-256";
            case SHA512:
                return "SHA-512";
            default:
                break;
        }
        return "";
    }

}
